/*
 * MediaSession.h
 *
 *  Created on: 2016年9月22日
 *      Author: zhengboyuan
 */

#ifndef MEDIASESSION_H_
#define MEDIASESSION_H_

#include "MediaSystem.h"
#include "Resip.h"
#include "MediaStream.h"
#include <deque>

#include "SharedPtr.h"
#include "TCriticalSection.h"



class MediaSession
{
public:
	enum State
	{
		kInit = 0,	/// 初始
        kPending,   /// 开始呼叫
		kOpened,	/// 建立成功
		kReady,		/// 就绪
		kClosed		/// 关闭
	};

	typedef std::deque< resip::ServerInviteSessionHandle >    		HandleArray;

public:
	MediaSession(int mediaType=av::MEDIA_TYPE_NONE);
	virtual ~MediaSession();

	/**
	 * 获取会话状态
	 * @return
	 */
	State getState();

	/**
	 * 设置会话状态
	 * @param state
	 */
	void setState(State state);

	/**
	 * 判断会话是否就绪, 即状态  = kReady
	 * @return
	 */
	bool isReady();

	/**
	 * 获取主呼用户
	 * @return
	 */
	resip::Data getCaller();

	void setCaller(const resip::Data& caller);

	int getMediaType();

	/**
	 * 获取媒体设备
	 * @return
	 */
	av::MediaSystem::Device& getMediaDev();

	void setMediaDev(const av::MediaSystem::Device& device);

	/**
	 * 获取媒体源
	 * @return
	 */
	av::MediaChannelPtr getMediaChannel();

	void setMediaChannel(av::MediaChannelPtr& channel);

	/**
	 * 添加用户呼叫
	 * @param handle
	 */
	void addUser(resip::ServerInviteSessionHandle& handle);

	/**
	 * 删除用户呼叫
	 * @param handle
	 * @return
	 */
	bool removeUser(resip::ServerInviteSessionHandle& handle);

	/**
	 * 移除首个用户呼叫
	 * @return
	 */
	resip::ServerInviteSessionHandle removeUser();

	/**
	 * 判断用户呼叫句柄是否存在?
	 * @param handle
	 * @return
	 */
	bool existUser(resip::ServerInviteSessionHandle& handle);

	size_t getUserCount();

	/**
	 * 获取所有用户呼叫句柄
	 * @return
	 */
	HandleArray getUsers();


	/**
	 * 设置设备呼叫会话句柄
	 * @param handle
	 */
	void setInviteSession(resip::ClientInviteSessionHandle handle);

	/**
	 * 获取设备呼叫会话句柄
	 * @return
	 */
	resip::ClientInviteSessionHandle getInviteSession();


	std::string getUri();

	bool hasTalker();
	bool setTalker(resip::ServerInviteSessionHandle handle);
	void clearTalker(resip::ServerInviteSessionHandle handle);
	void clearTalker();

protected:
	void setMediaType(int mediaType);

protected:
	State	m_state;

	resip::Data	m_caller;
	av::MediaSystem::Device	m_mediaDevice;
	int		m_mediaType;

	HandleArray	m_users;

	av::MediaChannelPtr		m_channel;

	comn::CriticalSection	m_cs;

	resip::ClientInviteSessionHandle	m_invite;

	resip::ServerInviteSessionHandle m_talker;

};


typedef std::shared_ptr< MediaSession >		MediaSessionPtr;



#endif /* MEDIASESSION_H_ */
